home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Users Group Library 1996 July
/
C-C++ Users Group Library July 1996.iso
/
listings
/
v_09_05
/
9n05059a
< prev
next >
Wrap
Text File
|
1991-02-05
|
11KB
|
508 lines
/*************************************
* *
* LINEAR & NONLINEAR VARIANCE *
* TEST PROGRAM *
* *
* M.E. Brandt, Ph.D. *
* 02/06/91 Revision *
* *
*************************************/
#include <stdio.h>
#include <math.h>
#include <malloc.h>
#define NMAX 1024
#define NBINS 10
#define MAX_DELAY 30
#define MAXRAND 32767.0
#define DBL_LEN sizeof(double)
#define PI 3.141592653589793
#define TWOPI (2.0 * PI)
double linvar(double *y, double *x, int nn);
double nonlinvar(double *x, double *y, int n, int nbins);
int number_bins(int x);
void estimate_delay(double *x, double *y, int n);
main()
{
int xx, i, j, nb, n, ch;
double *x, *y, scale, r2, h2, start,
noise, gain, a, inc, mean, num;
char u[3], c;
srand(1);
/* SELECT A FUNCTION TO TEST */
do {
printf("\n\nSelect a y vs. x function and ");
printf("compute variances:\n");
printf("\n1. y = ax + noise (linear)");
printf("\n2. y = sin(x) + noise");
printf("\n3. y = sgn(x)*(x*x) + noise");
printf("\n4. y = pow(3*x, 3) + noise");
printf("\n5. y = pow(5*x, 5) + noise");
printf("\n6. Exit");
printf("\n\nSelect 1-6: ");
scanf("%d", &ch);
if(ch == 6) exit(0);
do {
printf("\n\nHow many data points?: ");
scanf("%d", &n);
}
while(n > NMAX);
do {
printf("\n\nEnter noise gain: ");
scanf("%lf", &gain);
}
while(gain < 0.0 || gain > 1.0);
/* allocate space for x and y vectors */
if((x = (double *)malloc(n * DBL_LEN)) == NULL) {
fprintf(stderr, "\nMalloc error; x\n");
exit(1);
}
if((y = (double *)malloc(n * DBL_LEN)) == NULL) {
fprintf(stderr, "\nMalloc error; y\n");
exit(1);
}
/* generate a random uniformly distributed x[n]
between + or - 0.5
*/
for(i=0; i<n; i++) x[i] =
((double)rand()/MAXRAND - 0.5);
/* choose y[n] */
switch(ch) {
case 1: printf("\nEnter a: ");
scanf("%lf", &a);
for(i=0; i<n; i++) {
noise = gain *
((double)rand()/MAXRAND - 0.5);
y[i] = a * x[i] + noise;
}
break;
case 2: for(i=0; i<n; i++) {
noise = gain *
((double)rand()/MAXRAND - 0.5);
y[i] = sin(TWOPI * x[i]) + noise;
}
break;
case 3: for(i=0; i<n; i++) {
noise = gain *
((double)rand()/MAXRAND - 0.5);
y[i] = (x[i] * x[i]);
if(x[i] < 0.0) y[i] *= -1.0;
y[i] += noise;
}
break;
case 4: for(i=0; i<n; i++) {
noise = gain *
((double)rand()/MAXRAND - 0.5);
y[i] = pow(3.0*x[i], 3.0) + noise;
}
break;
case 5: for(i=0; i<n; i++) {
noise = gain *
((double)rand()/MAXRAND - 0.5);
y[i] = pow(5.0*x[i], 5.0) + noise;
}
break;
default: break;
}
printf("\nTest delay estimation <y/n>?: ");
scanf("%s", u);
c = toupper(*u);
if(c == 'Y') {
estimate_delay(x, y, n);
continue;
}
/* compute linear variance of x vs. y */
r2 = linvar(x, y, n);
printf("\nLinear r2(x,y) = %f\n", r2);
/* choose number of bins */
nb = number_bins(n);
/* compute nonlinear variance of x vs. y */
h2 = nonlinvar(x, y, n, nb);
printf("\nNonlinear h2(x,y) = %f\n", h2);
/* y vs. x */
r2 = linvar(y, x, n);
printf("\nLinear r2(y,x) = %f\n", r2);
h2 = nonlinvar(y, x, n, nb);
printf("\nNonlinear h2(y,x) = %f\n", h2);
free(x); free(y);
}
while(1);
}
/* routine to find variances & delay between 2 lagged
signals */
double buf[NMAX+MAX_DELAY], r2[MAX_DELAY+10],
h2[MAX_DELAY+10];
void estimate_delay(double *x, double *y, int n)
{
int i, j, d, delay, lag, max_lag, np, nb;
double max;
do {
printf("\nEnter delay between x and y in samples: ");
scanf("%d", &delay);
}
while((d = abs(delay)) > MAX_DELAY);
for(i=0; i<d; i++)
buf[i] = ((double)rand()/MAXRAND - 0.5);
max_lag = d + 10;
if(delay > 0) { /* y lags x */
/* move y to buf */
for(j=0, i=d; j<n; i++, j++) buf[i] = y[j];
for(lag=0; lag<max_lag; lag++) {
np = n - lag; /* compute across less points */
/* get linear variance at lag */
r2[lag] = linvar(x, &buf[lag], np);
nb = number_bins(np);
/* get nonlinear variance at lag */
h2[lag] = nonlinvar(x, &buf[lag], np, nb);
}
}
else if(delay < 0) { /* x lags y */
for(j=0, i=d; j<n; i++, j++) buf[i] = x[j];
for(lag=0; lag<max_lag; lag++) {
np = n - lag;
r2[lag] = linvar(&buf[lag], y, np);
nb = number_bins(np);
h2[lag] = nonlinvar(&buf[lag], y, np, nb);
}
}
/* find maximum r2 and corresponding delay */
max = r2[0];
for(i=1; i<max_lag; i++)
if(r2[i] > max) {max = r2[i]; j = i;}
if(delay < 0) j = -j;
printf("\nTrue delay = %d; maximum r2 = %f \
found @ sample %d\n",
delay, max, j);
/* find maximum h2 and corresponding delay */
max = h2[0];
for(i=1; i<max_lag; i++)
if(h2[i] > max) {max = h2[i]; j = i;}
if(delay < 0) j = -j;
printf("\nTrue delay = %d; maximum h2 = %f \
found @ sample %d\n",
delay, max, j);
}
/* compute number of bins for nonlinear variance calc. */
int number_bins(int x)
{
int y;
if(x < 129) y = NBINS - 4;
else
if(x < 257) y = NBINS - 3;
else
if(x < 513) y = NBINS - 2;
else y = NBINS;
return y;
}
/* routine to compute linear variance measure */
double linvar(double *y, double *x, int nn)
{
register int j;
double z, smx, smy, sqx, sqy, sxy, corr;
double sqrt(), varx, vary, cov, nnn;
/* initialize values */
nnn = (double)nn;
corr = sqy = 0.0;
smx = 0.0;
smy = 0.0;
sqx = 0.0;
sxy = 0.0;
for(j=0; j<nn; j++) {
smx += x[j];
smy += y[j];
sqx += (x[j] * x[j]);
sxy += (x[j] * y[j]);
sqy += (y[j] * y[j]);
} /* end for */
/* Compute covariance and variances */
cov = (nnn * sxy) - (smx * smy);
varx = (nnn * sqx) - (smx * smx);
vary = (nnn * sqy) - (smy * smy);
z = sqrt(varx * vary);
if(z != 0.0) corr = cov / z;
else corr = 0.0;